Skip to content

Conversation

@alkatrivedi
Copy link
Contributor

fixes: #2368

@alkatrivedi alkatrivedi requested review from a team as code owners August 4, 2025 06:26
@product-auto-label product-auto-label bot added size: s Pull request size is small. api: spanner Issues related to the googleapis/nodejs-spanner API. size: xl Pull request size is extra large. and removed size: s Pull request size is small. labels Aug 4, 2025
@product-auto-label product-auto-label bot added size: m Pull request size is medium. size: xl Pull request size is extra large. and removed size: xl Pull request size is extra large. size: m Pull request size is medium. labels Aug 4, 2025
@product-auto-label product-auto-label bot added size: m Pull request size is medium. size: xl Pull request size is extra large. and removed size: xl Pull request size is extra large. size: m Pull request size is medium. labels Aug 4, 2025
@product-auto-label product-auto-label bot added size: m Pull request size is medium. and removed size: xl Pull request size is extra large. labels Aug 4, 2025
@alkatrivedi alkatrivedi force-pushed the fix-race-condition branch 2 times, most recently from 7382103 to 414cd05 Compare August 4, 2025 11:22
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: m Pull request size is medium. labels Aug 4, 2025
@product-auto-label product-auto-label bot added size: m Pull request size is medium. size: xl Pull request size is extra large. and removed size: xl Pull request size is extra large. size: m Pull request size is medium. labels Aug 4, 2025
Comment on lines 9196 to 9197
process.env.GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS = 'true';
process.env.GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW = 'true';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this condition, we have 2 separate pipeline for mux and non-mux.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it was for local testing. I have removed it

Comment on lines 9218 to 9211
while (sync.count !== sync.target) {
// wait for 500 milliseconds
await new Promise(resolve => setTimeout(resolve, 500));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add a wait after you receive precommittoken, so dont use mutation only case but execute a read before the commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for this catch, I have updated the test to execute a read before mutations. now we will have a precommit token while committing the transactions

@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: m Pull request size is medium. labels Aug 5, 2025
@product-auto-label product-auto-label bot added size: m Pull request size is medium. and removed size: xl Pull request size is extra large. labels Aug 5, 2025
@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: m Pull request size is medium. labels Aug 5, 2025
/** Edition enum. */
enum Edition {
EDITION_UNKNOWN = 0,
EDITION_LEGACY = 900,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

owlbot is pushing these changes, these are not manual

await Promise.all(promises);
});

it('POSTGRESQL should insert and commit transactions when running parallely', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have to write this specifically for PG_DIALECT? There's no difference between dialects here right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I have removed it

});

it('should pass back the session and txn', done => {
const fakeTxn = new FakeTransaction() as unknown as Transaction;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where are we mocking session.!transaction method? Ideally this test should fail since we removed the assignment right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have removed the assignment but we are returning the transaction using transaction method defined in Session class.

session!.transaction((session!.parent as Database).queryOptions_),

test/spanner.ts Outdated
);

// assert that seqNum is different in both the commit request
assert.notEqual(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you expect seqNum to be different?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess because mockspanner return a random number for sequence number , randomInt(1, 1000),

But thats not a valid assertion. SeqNum may or maynot be same for 2 transactions running in parallel.

I am not sure if the seqNum is supposed to be an incremental number from 1...n . If yes, then mockSpanner should have followed the same logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if the seqNum is supposed to be an incremental number from 1...n

yes, I have updated the mock spanner logic and hence, the test case to run read before performing mutations. now we will be sure that precommit token is there for both the transactions while making commit request.

commitTransaction(done, PG_DATABASE, postgreSqlTable);
});

describe('when multiplexed session is enabled for read write', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This need not be specific to multiplexed session, the scenario we are trying to test here is that parallel transaction should work , for both mux and non-mux. So describe should mention that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, correct

I have updated the test name, it will anyway will be running against both the pipelines, one with mux enabled and another with mux not enabled

precommitToken: {
precommitToken: fakeRetryToken,
seqNum: 1,
seqNum: 2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
seqNum: 2,
// Retry should have a higher sequence number
seqNum: 2,

@alkatrivedi alkatrivedi added kokoro:force-run Add this label to force Kokoro to re-run the tests. owlbot:run Add this label to trigger the Owlbot post processor. labels Aug 8, 2025
@gcf-owl-bot gcf-owl-bot bot removed the owlbot:run Add this label to trigger the Owlbot post processor. label Aug 8, 2025
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Aug 8, 2025
@alkatrivedi alkatrivedi merged commit f8b6f63 into main Aug 10, 2025
23 of 24 checks passed
@alkatrivedi alkatrivedi deleted the fix-race-condition branch August 10, 2025 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: spanner Issues related to the googleapis/nodejs-spanner API. size: xl Pull request size is extra large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Race Condition in Multiplexed Session

5 participants